home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / gtlayout-source.lha / LTP_LayoutGroup.c < prev    next >
C/C++ Source or Header  |  1996-10-03  |  20KB  |  825 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1996 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #ifdef NOT_FUNCTIONAL
  15.  
  16.     /* LTP_ShuffleGroup(LayoutHandle *Handle,ObjectNode *Group):
  17.      *
  18.      *    Propagate size relationships between groups on the
  19.      *    same tree level.
  20.      *
  21.      *    On second thought, this was not such a good idea after
  22.      *    all. I'll redo the stuff when I find the time.
  23.      */
  24.  
  25. VOID
  26. LTP_ShuffleGroup(LayoutHandle *Handle,ObjectNode *Group)
  27. {
  28.     if(!Handle->Failed)
  29.     {
  30.         ObjectNode    *Node;
  31.         LONG         WidthCount        = 0,
  32.                      HeightCount    = 0;
  33.  
  34.             // First step: count the number of nodes which should share
  35.             //             the sizes with other groups. Validate the
  36.             //             group relationships on the fly, cancelling
  37.             //             links which point to nonexistant objects.
  38.  
  39.         SCANGROUP(Group,Node)
  40.         {
  41.             if(Node->Type == GROUP_KIND)
  42.             {
  43.                     // Use the size of another group?
  44.  
  45.                 if(Node->Special.Group.UseWidth != -1)
  46.                 {
  47.                     ObjectNode    *Other;
  48.                     BOOL         GotIt = FALSE;
  49.  
  50.                         // Scan the list for the group in question...
  51.  
  52.                     SCANGROUP(Group,Other)
  53.                     {
  54.                             // Is it this one?
  55.  
  56.                         if(Other != Node && Node->ID == Node->Special.Group.UseWidth)
  57.                         {
  58.                             GotIt = TRUE;
  59.                             break;
  60.                         }
  61.                     }
  62.  
  63.                         // If this one is valid, update the counter,
  64.                         // else cancel the link
  65.  
  66.                     if(GotIt)
  67.                         WidthCount++;
  68.                     else
  69.                         Node->Special.Group.UseWidth = -1;
  70.                 }
  71.  
  72.                 if(Node->Special.Group.UseHeight != -1)
  73.                 {
  74.                     ObjectNode    *Other;
  75.                     BOOL         GotIt = FALSE;
  76.  
  77.                     SCANGROUP(Group,Other)
  78.                     {
  79.                         if(Other != Node && Node->ID == Node->Special.Group.UseHeight)
  80.                         {
  81.                             GotIt = TRUE;
  82.                             break;
  83.                         }
  84.                     }
  85.  
  86.                     if(GotIt)
  87.                         HeightCount++;
  88.                     else
  89.                         Node->Special.Group.UseHeight = -1;
  90.                 }
  91.             }
  92.         }
  93.  
  94.             // Second step: If any valid relationships were found,
  95.             //              propagate the sizes.
  96.  
  97.         if(WidthCount || HeightCount)
  98.         {
  99.             ObjectNode **Table;
  100.             LONG Total = sizeof(ObjectNode *) * MAX(WidthCount,HeightCount);
  101.  
  102.                 // Some temporary storage for keeping the nodes
  103.  
  104.             if(Table = (ObjectNode **)LTP_Alloc(Handle,Total))
  105.             {
  106.                 LONG Handled = 0,Collected = 0,Wanted = -1,i,MaxWidth,MaxHeight;
  107.  
  108.                     // Loop until all width relationships are resolved.
  109.  
  110.                 while(Handled < WidthCount)
  111.                 {
  112.                     Node = (ObjectNode *)Group->Special.Group.ObjectList.mlh_Head;
  113.  
  114.                         // Scan until we hit the end
  115.  
  116.                     while(Node->Node.mln_Succ)
  117.                     {
  118.                             // Is this a group we didn't check yet, but would
  119.                             // need to take a look at?
  120.  
  121.                         if(Node->Type == GROUP_KIND && Node->Special.Group.UseWidth != -1 && !(Node->Special.Group.MiscFlags & GROUPF_WidthDone))
  122.                         {
  123.                                 // Should we keep this one?
  124.  
  125.                             if(Wanted == -1 || Node->ID == Wanted)
  126.                             {
  127.                                     // Keep this one
  128.  
  129.                                 Table[Collected++] = Node;
  130.  
  131.                                     // Don't check this one again
  132.  
  133.                                 Node->Special.Group.MiscFlags |= GROUPF_WidthDone;
  134.  
  135.                                     // We'll search for this one unless
  136.                                     // it points nowhere
  137.  
  138.                                 if((Wanted = Node->Special.Group.UseWidth) == -1)
  139.                                     break;
  140.                                 else    // Start again...
  141.                                     Node = (ObjectNode *)Group->Special.Group.ObjectList.mlh_Head;
  142.                             }
  143.                             else
  144.                                 Node = (ObjectNode *)Node->Node.mln_Succ;
  145.                         }
  146.                         else
  147.                             Node = (ObjectNode *)Node->Node.mln_Succ;
  148.                     }
  149.  
  150.                         // Determine maximum width of objects
  151.  
  152.                     for(i = MaxWidth = 0 ; i < Collected ; i++)
  153.                     {
  154.                         if(Table[i]->Width > MaxWidth)
  155.                             MaxWidth = Table[i]->Width;
  156.                     }
  157.  
  158.                         // Make all objects as large as the largest object
  159.  
  160.                     for(i = 0 ; i < Collected ; i++)
  161.                         Table[i]->Width = MaxWidth;
  162.  
  163.                         // Update the counter
  164.  
  165.                     Handled += Collected;
  166.  
  167.                         // Scan until all references are resolved
  168.  
  169.                     Collected = 0;
  170.                 }
  171.  
  172.                 Handled = 0;
  173.  
  174.                 while(Handled < HeightCount)
  175.                 {
  176.                     Node = (ObjectNode *)Group->Special.Group.ObjectList.mlh_Head;
  177.  
  178.                     while(Node->Node.mln_Succ)
  179.                     {
  180.                         if(Node->Type == GROUP_KIND && Node->Special.Group.UseHeight != -1 && !(Node->Special.Group.MiscFlags & GROUPF_HeightDone))
  181.                         {
  182.                             if(Wanted == -1 || Node->ID == Wanted)
  183.                             {
  184.                                 Table[Collected++] = Node;
  185.  
  186.                                 Node->Special.Group.MiscFlags |= GROUPF_HeightDone;
  187.  
  188.                                 if((Wanted = Node->Special.Group.UseHeight) == -1)
  189.                                     break;
  190.                                 else
  191.                                     Node = (ObjectNode *)Group->Special.Group.ObjectList.mlh_Head;
  192.                             }
  193.                             else
  194.                                 Node = (ObjectNode *)Node->Node.mln_Succ;
  195.                         }
  196.                         else
  197.                             Node = (ObjectNode *)Node->Node.mln_Succ;
  198.                     }
  199.  
  200.                     for(i = MaxHeight = 0 ; i < Collected ; i++)
  201.                     {
  202.                         if(Table[i]->Height > MaxHeight)
  203.                             MaxHeight = Table[i]->Height;
  204.                     }
  205.  
  206.                     for(i = 0 ; i < Collected ; i++)
  207.                         Table[i]->Height = MaxHeight;
  208.  
  209.                     Handled += Collected;
  210.  
  211.                     Collected = 0;
  212.                 }
  213.  
  214.                 LTP_Free(Handle,Table,Total);
  215.             }
  216.         }
  217.  
  218.             // Step three: do the just the same to all the other groups
  219.             //             (tail recursion).
  220.  
  221.         SCANGROUP(Group,Node)
  222.         {
  223.             if(Node->Type == GROUP_KIND)
  224.                 LTP_ShuffleGroup(Handle,Node);
  225.         }
  226.     }
  227. }
  228. #endif    // NOT_FUNCTIONAL
  229.  
  230. VOID
  231. LTP_LayoutGroup(LayoutHandle *Handle,ObjectNode *Group)
  232. {
  233.     if(!Handle->Failed)
  234.     {
  235.         ObjectNode    *Node;
  236.         ObjectNode    *ReturnKey;
  237.         ObjectNode    *EscKey;
  238.         ObjectNode    *CursorKey;
  239.         ObjectNode    *TabKey;
  240.         ObjectNode    *ActiveString;
  241.         LONG         Left;
  242.         LONG         Top;
  243.         LONG         Width;
  244.         LONG         Height;
  245.         LONG         MaxWidth;
  246.         LONG         MaxHeight;
  247.         BOOL         DefaultCorrection;
  248.  
  249.         Left                = 0;
  250.         Top                    = 0;
  251.         ReturnKey            = NULL;
  252.         EscKey                = NULL;
  253.         CursorKey            = NULL;
  254.         TabKey                = NULL;
  255.         ActiveString        = NULL;
  256.         DefaultCorrection    = FALSE;
  257.         MaxWidth            = 0;
  258.         MaxHeight            = 0;
  259.  
  260.         SCANGROUP(Group,Node)
  261.         {
  262.             LTP_DetermineSize(Handle,Node);
  263.  
  264.             switch(Node->Type)
  265.             {
  266.                 case BUTTON_KIND:
  267.  
  268.                     if(Node->Special.Button.ReturnKey)
  269.                         ReturnKey = Node;
  270.                     else
  271.                     {
  272.                         if(Node->Special.Button.EscKey)
  273.                             EscKey = Node;
  274.                     }
  275.  
  276.                     DefaultCorrection |= Node->Special.Button.DefaultCorrection;
  277.  
  278.                     break;
  279.  
  280.                 case CYCLE_KIND:
  281.  
  282.                     if(Node->Special.Cycle.TabKey)
  283.                         TabKey = Node;
  284.  
  285.                     break;
  286.  
  287. #if defined(DO_POPUP_KIND) && defined(DO_BOOPSI_KIND)
  288.                 case POPUP_KIND:
  289.  
  290.                     if(Node->Special.Popup.TabKey)
  291.                         TabKey = Node;
  292.  
  293.                     break;
  294. #endif
  295.  
  296. #if defined(DO_TAB_KIND) && defined(DO_BOOPSI_KIND)
  297.                 case TAB_KIND:
  298.  
  299.                     if(Node->Special.Tab.TabKey)
  300.                         TabKey = Node;
  301.  
  302.                     break;
  303. #endif
  304.                 case MX_KIND:
  305.  
  306.                     if(Node->Special.Radio.TabKey)
  307.                         TabKey = Node;
  308.  
  309.                     break;
  310.  
  311.                 case PASSWORD_KIND:
  312.                 case STRING_KIND:
  313.  
  314.                     if(Node->Special.String.Activate)
  315.                         ActiveString = Node;
  316.  
  317.                     break;
  318.  
  319.                 case INTEGER_KIND:
  320.  
  321.                     if(Node->Special.Integer.Activate)
  322.                         ActiveString = Node;
  323.  
  324.                     break;
  325.  
  326.                 case LISTVIEW_KIND:
  327.  
  328.                     if(Node->Special.List.CursorKey)
  329.                         CursorKey = Node;
  330.  
  331.                     break;
  332.             }
  333.  
  334.             if(Node->Width > MaxWidth)
  335.                 MaxWidth = Node->Width;
  336.  
  337.             if(Node->Height > MaxHeight)
  338.                 MaxHeight = Node->Height;
  339.         }
  340.  
  341.         if(ReturnKey || DefaultCorrection)
  342.         {
  343.             SCANGROUP(Group,Node)
  344.             {
  345. #ifdef OLD_STYLE_DEFAULT_KEY
  346.                 Node->GroupIndent = TRUE;
  347.  
  348.                 Node->Width        += 4 + 4;
  349.                 Node->Height    += 2 + 2;
  350. #else
  351.                 Node->Width        += 1 + 1;
  352.                 Node->Height    += 1 + 1;
  353. #endif
  354.                 if(Node->Width > MaxWidth)
  355.                     MaxWidth = Node->Width;
  356.  
  357.                 if(Node->Height > MaxHeight)
  358.                     MaxHeight = Node->Height;
  359.             }
  360.         }
  361.  
  362.         if(Group->Special.Group.SameSize)
  363.         {
  364.             SCANGROUP(Group,Node)
  365.             {
  366.                 if(Node->Width < MaxWidth && Node->Type != YBAR_KIND && Node->Type != CHECKBOX_KIND)
  367.                 {
  368.                     if(Node->Type == GROUP_KIND && !Node->Special.Group.NoIndent)
  369.                         Node->Special.Group.ExtraLeft += (MaxWidth - Node->Width) / 2;
  370.  
  371.                     Node->Width = MaxWidth;
  372.                 }
  373.  
  374.                 if(Node->Height < MaxHeight && Node->Type != XBAR_KIND && Node->Type != CHECKBOX_KIND)
  375.                 {
  376.                     if(Node->Type == GROUP_KIND && !Node->Special.Group.NoIndent)
  377.                         Node->Special.Group.ExtraTop += (MaxHeight - Node->Height) / 2;
  378.  
  379.                     Node->Height = MaxHeight;
  380.                 }
  381.             }
  382.         }
  383.  
  384.         if(Group->Special.Group.Horizontal)
  385.         {
  386.             LONG x,y,w,MaxTop = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  387.  
  388.             if(Group->Node.mln_Pred->mln_Pred && Group->Special.Group.LastAttributes)
  389.             {
  390.                 ObjectNode *LastGroup = (ObjectNode *)Group->Node.mln_Pred;
  391.  
  392.                 MaxTop        = LastGroup->Special.Group.MaxOffset;
  393.                 MaxHeight    = LastGroup->Special.Group.MaxSize;
  394.             }
  395.  
  396.             SCANGROUP(Group,Node)
  397.             {
  398.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  399.                 {
  400.                     if(!Group->Special.Group.Paging && Count++)
  401.                     {
  402.                         if(Node->ExtraSpace > 0)
  403.                             x = Left + Node->ExtraSpace * Handle->InterWidth;
  404.                         else
  405.                         {
  406.                             if(Node->ExtraSpace < 0)
  407.                                 x = Left - Node->ExtraSpace;
  408.                             else
  409.                                 x = Left + Handle->InterWidth;
  410.                         }
  411.                     }
  412.                     else
  413.                         x = Left;
  414.  
  415.                     y = Top;
  416.                     w = Node->Width;
  417.  
  418.                     switch(Node->LabelPlace)
  419.                     {
  420.                         case PLACE_LEFT:
  421.  
  422.                             if(Node->Type == MX_KIND)
  423.                             {
  424.                                 x += Node->Special.Radio.LabelWidth + INTERWIDTH;
  425.  
  426.                                 if(Node->Label)
  427.                                 {
  428.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  429.                                         x += Node->LabelWidth + INTERWIDTH;
  430.                                     else
  431.                                         w += INTERWIDTH + Node->LabelWidth;
  432.                                 }
  433.                             }
  434.                             else
  435.                             {
  436.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  437.                                     x += Node->LabelWidth + INTERWIDTH;
  438.                             }
  439.  
  440.                             break;
  441.  
  442.                         case PLACE_RIGHT:
  443.  
  444.                             if(Node->Type == MX_KIND)
  445.                             {
  446.                                 w += INTERWIDTH + Node->Special.Radio.LabelWidth;
  447.  
  448.                                 if(Node->Label)
  449.                                 {
  450.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  451.                                         x += Node->LabelWidth + INTERWIDTH;
  452.                                     else
  453.                                         w += INTERWIDTH + Node->LabelWidth;
  454.                                 }
  455.                             }
  456.                             else
  457.                             {
  458.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  459.                                     w += INTERWIDTH + Node->LabelWidth;
  460.                             }
  461.  
  462.                             break;
  463.  
  464.                         case PLACE_ABOVE:
  465.  
  466.                             if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  467.                             {
  468.                                 if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  469.                                     y += Node->Special.List.FixedGlyphHeight + INTERHEIGHT;
  470.                                 else
  471.                                     y += Handle->GlyphHeight + INTERHEIGHT;
  472.                             }
  473.  
  474.                             break;
  475.                     }
  476.  
  477.                     if(Node->Type == SLIDER_KIND)
  478.                     {
  479.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_RIGHT && Node->Special.Slider.LevelFormat)
  480.                             w += INTERWIDTH + Node->Special.Slider.LevelWidth;
  481.  
  482.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT && Node->Special.Slider.LevelFormat)
  483.                             x += INTERWIDTH + Node->Special.Slider.LevelWidth;
  484.                     }
  485.  
  486. #ifdef DO_LEVEL_KIND
  487.                     if(Node->Type == LEVEL_KIND)
  488.                     {
  489.                         if(Node->Special.Level.LevelPlace == PLACETEXT_RIGHT)
  490.                             w += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  491.  
  492.                         if(Node->Special.Level.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT)
  493.                             x += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  494.                     }
  495. #endif    /* DO_LEVEL_KIND */
  496.  
  497.                     if(Node->Type == LISTVIEW_KIND && Node->Special.List.ExtraLabelWidth)
  498.                         x += Node->Special.List.ExtraLabelWidth + INTERWIDTH;
  499.  
  500.                     if(y > MaxTop)
  501.                         MaxTop = y;
  502.  
  503.                     if(Node->Height > MaxHeight)
  504.                         MaxHeight = Node->Height;
  505.  
  506.                     if(Node->LabelPlace == PLACE_BELOW && Node->Label)
  507.                     {
  508.                         LONG Height;
  509.  
  510.                         if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  511.                             Height = Node->Height + INTERHEIGHT + Node->Special.List.FixedGlyphHeight;
  512.                         else
  513.                             Height = Node->Height + INTERHEIGHT + Handle->GlyphHeight;
  514.  
  515.                         if(Height > MaxHeight)
  516.                             MaxHeight = Height;
  517.                     }
  518.                     else
  519.                     {
  520.                         if(Node->Height > MaxHeight)
  521.                             MaxHeight = Node->Height;
  522.                     }
  523.  
  524.                     if(x + w > MaxWidth)
  525.                         MaxWidth = x+w;
  526.  
  527.                     Node->Left = x;
  528.  
  529.                     if(!Group->Special.Group.Paging)
  530.                         Left = x + w;
  531.                 }
  532.             }
  533.  
  534.             SCANGROUP(Group,Node)
  535.             {
  536.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  537.                 {
  538.                     Node->Top = MaxTop;
  539.  
  540.                     if(Node->Height < MaxHeight)
  541.                     {
  542. #ifdef DO_BOOPSI_KIND
  543.                         if((Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) || Node->Type == LISTVIEW_KIND || (Node->Type == BOOPSI_KIND && !Node->Special.BOOPSI.ExactHeight))
  544. #else
  545.                         if((Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) || Node->Type == LISTVIEW_KIND || Node->Type == BOOPSI_KIND)
  546. #endif    /* DO_BOOPSI_KIND */
  547.                             Node->Height = MaxHeight;
  548.                         else
  549.                         {
  550.                             if(Node->Type == GROUP_KIND)
  551.                             {
  552.                                 if(Node->Special.Group.Spread)
  553.                                     LTP_Spread(Handle,Node,Node->Width,MaxHeight);
  554.                                 else
  555.                                 {
  556.                                     if(!Node->Special.Group.NoIndent)
  557.                                         Node->Special.Group.ExtraTop += (MaxHeight - Node->Height) / 2; /* !FIX! */
  558.                                 }
  559.  
  560.                                 Node->Height = MaxHeight;
  561.                             }
  562.                         }
  563.                     }
  564.                 }
  565.             }
  566.  
  567.             Group->Special.Group.MaxOffset = MaxTop;
  568.             Group->Special.Group.MaxSize   = MaxHeight;
  569.  
  570.             if(Group->Special.Group.Paging)
  571.                 Width = MaxWidth;
  572.             else
  573.                 Width = Left;
  574.  
  575.             Height = MaxTop + MaxHeight;
  576.         }
  577.         else
  578.         {
  579.             LONG x,y,w,MaxLeft = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  580.  
  581.             if(Group->Node.mln_Pred->mln_Pred && Group->Special.Group.LastAttributes)
  582.             {
  583.                 ObjectNode *LastGroup = (ObjectNode *)Group->Node.mln_Pred;
  584.  
  585.                 MaxLeft     = LastGroup->Special.Group.MaxOffset;
  586.                 MaxWidth    = LastGroup->Special.Group.MaxSize;
  587.             }
  588.  
  589.             SCANGROUP(Group,Node)
  590.             {
  591.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  592.                 {
  593.                     if(!Group->Special.Group.Paging && Count++)
  594.                     {
  595.                         if(Node->ExtraSpace > 0)
  596.                             y = Top + Node->ExtraSpace * Handle->InterHeight;
  597.                         else
  598.                         {
  599.                             if(Node->ExtraSpace < 0)
  600.                                 y = Top - Node->ExtraSpace;
  601.                             else
  602.                                 y = Top + Handle->InterHeight;
  603.                         }
  604.                     }
  605.                     else
  606.                         y = Top;
  607.  
  608.                     w = Node->Width;
  609.                     x = Left;
  610.  
  611.                     switch(Node->LabelPlace)
  612.                     {
  613.                         case PLACE_LEFT:
  614.  
  615.                             if(Node->Type == MX_KIND)
  616.                             {
  617.                                 x += Node->Special.Radio.LabelWidth + INTERWIDTH;
  618.  
  619.                                 if(Node->Label)
  620.                                 {
  621.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  622.                                         x += Node->LabelWidth + INTERWIDTH;
  623.                                 }
  624.                             }
  625.                             else
  626.                             {
  627.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  628.                                     x += Node->LabelWidth + INTERWIDTH;
  629.                             }
  630.  
  631.                             break;
  632.  
  633.                         case PLACE_RIGHT:
  634.  
  635.                             if(Node->Type == MX_KIND)
  636.                             {
  637.                                 w += INTERWIDTH + Node->Special.Radio.LabelWidth;
  638.  
  639.                                 if(Node->Label)
  640.                                 {
  641.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  642.                                         x += Node->LabelWidth + INTERWIDTH;
  643.                                     else
  644.                                         w += INTERWIDTH + Node->LabelWidth;
  645.                                 }
  646.                             }
  647.                             else
  648.                             {
  649.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  650.                                     w += INTERWIDTH + Node->LabelWidth;
  651.                             }
  652.  
  653.                             break;
  654.  
  655.                         case PLACE_ABOVE:
  656.  
  657.                             if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  658.                             {
  659.                                 if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  660.                                     y += Node->Special.List.FixedGlyphHeight + INTERHEIGHT;
  661.                                 else
  662.                                     y += Handle->GlyphHeight + INTERHEIGHT;
  663.                             }
  664.  
  665.                             break;
  666.                     }
  667.  
  668.                     if(Node->Type == SLIDER_KIND)
  669.                     {
  670.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_RIGHT && Node->Special.Slider.LevelFormat)
  671.                             w += INTERWIDTH + Node->Special.Slider.LevelWidth;
  672.  
  673.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT && Node->Special.Slider.LevelFormat)
  674.                             x += INTERWIDTH + Node->Special.Slider.LevelWidth;
  675.                     }
  676.  
  677. #ifdef DO_LEVEL_KIND
  678.                     if(Node->Type == LEVEL_KIND)
  679.                     {
  680.                         if(Node->Special.Level.LevelPlace == PLACETEXT_RIGHT)
  681.                             w += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  682.  
  683.                         if(Node->Special.Level.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT)
  684.                             x += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  685.                     }
  686. #endif    /* DO_LEVEL_KIND */
  687.                     if(Node->Type == LISTVIEW_KIND && Node->Special.List.ExtraLabelWidth)
  688.                         x += Node->Special.List.ExtraLabelWidth + INTERWIDTH;
  689.  
  690.                     if(x > MaxLeft)
  691.                         MaxLeft = x;
  692.  
  693.                     if(w > MaxWidth)
  694.                         MaxWidth = w;
  695.  
  696.                     if(y + Node->Height > MaxHeight)
  697.                         MaxHeight = y + Node->Height;
  698.  
  699.                     Node->Top = y;
  700.  
  701.                     if(!Group->Special.Group.Paging)
  702.                         Top = y + Node->Height;
  703.  
  704.                     if(Node->LabelPlace == PLACE_BELOW && Node->Label)
  705.                     {
  706.                         if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  707.                             Top += INTERHEIGHT + Node->Special.List.FixedGlyphHeight;
  708.                         else
  709.                             Top += INTERHEIGHT + Handle->GlyphHeight;
  710.                     }
  711.                 }
  712.             }
  713.  
  714.             SCANGROUP(Group,Node)
  715.             {
  716.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  717.                 {
  718.                     Node->Left = MaxLeft;
  719.  
  720.                     if(Node->Type == GROUP_KIND && Group->Special.Group.Paging && !Node->Special.Group.NoIndent)
  721.                         Node->Special.Group.ExtraTop += (MaxHeight - Node->Height) / 2;
  722.  
  723.                     if(Node->Width < MaxWidth)
  724.                     {
  725.                         if(Node->Type == GROUP_KIND)
  726.                         {
  727.                             if(Node->Special.Group.Spread)
  728.                                 LTP_Spread(Handle,Node,MaxWidth,Node->Height);
  729.                             else
  730.                             {
  731.                                 if(!Node->Special.Group.NoIndent)
  732.                                     Node->Special.Group.ExtraLeft += (MaxWidth - Node->Width) / 2;
  733.                             }
  734.  
  735.                             Node->Width = MaxWidth;
  736.                         }
  737.                         else
  738.                         {
  739. #ifdef DO_BOOPSI_KIND
  740.                             if((Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) || (Node->Type == LISTVIEW_KIND && !Node->Special.List.LockSize) || (Node->Type == TEXT_KIND && !Node->Special.Text.LockSize) || Node->Type == GAUGE_KIND || Node->Type == NUMBER_KIND || Node->Type == CYCLE_KIND || LIKE_STRING_KIND(Node) || Node->Type == INTEGER_KIND || Node->Type == BUTTON_KIND || Node->Type == BOX_KIND || Node->Type == SCROLLER_KIND || Node->Type == SLIDER_KIND || Node->Type == LEVEL_KIND || (Node->Type == BOOPSI_KIND && !Node->Special.BOOPSI.ExactWidth) || Node->Type == POPUP_KIND || Node->Type == TAB_KIND || Node->Type == BLANK_KIND)
  741. #else
  742.                             if((Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) || (Node->Type == LISTVIEW_KIND && !Node->Special.List.LockSize) || (Node->Type == TEXT_KIND && !Node->Special.Text.LockSize) || Node->Type == GAUGE_KIND || Node->Type == NUMBER_KIND || Node->Type == CYCLE_KIND || LIKE_STRING_KIND(Node) || Node->Type == INTEGER_KIND || Node->Type == BUTTON_KIND || Node->Type == BOX_KIND || Node->Type == SCROLLER_KIND || Node->Type == SLIDER_KIND || Node->Type == LEVEL_KIND || Node->Type == BLANK_KIND)
  743. #endif    /* DO_BOOPSI_KIND */
  744.                             {
  745.                                 if(Node->Label && Node->LabelPlace == PLACE_RIGHT)
  746.                                     Node->Width = MaxWidth - (INTERWIDTH + Node->LabelWidth);
  747.                                 else
  748.                                     Node->Width = MaxWidth;
  749.                             }
  750.                         }
  751.                     }
  752.                 }
  753.             }
  754.  
  755.             Group->Special.Group.MaxOffset  = MaxLeft;
  756.             Group->Special.Group.MaxSize    = MaxWidth;
  757.  
  758.             if(Group->Special.Group.Paging)
  759.                 Height = MaxHeight;
  760.             else
  761.                 Height = Top;
  762.  
  763.             Width = MaxLeft + MaxWidth;
  764.         }
  765.  
  766.         Group->Left        = 0;
  767.         Group->Top        = 0;
  768.         Group->Width    = Width;
  769.         Group->Height    = Height;
  770.  
  771.         if(Group->Label || Group->Special.Group.Frame)
  772.         {
  773.             if(Group->Label)
  774.             {
  775.                 Group->LabelWidth = LT_LabelWidth(Handle,Group->Label) + 2 * Handle->GlyphWidth;
  776.  
  777.                 Group->Height += Handle->GlyphHeight + 2 * Handle->InterHeight + 3;
  778.             }
  779.             else
  780.             {
  781.                 Group->LabelWidth = 0;
  782.  
  783.                 Group->Height += 2 + 2 * Handle->InterHeight + 3;
  784.             }
  785.  
  786.             if(Group->LabelWidth > Group->Width)
  787.             {
  788.                 if(!Node->Special.Group.NoIndent)
  789.                     Group->Special.Group.ExtraLeft += (Group->LabelWidth - Group->Width) / 2;
  790.  
  791.                 Group->Width = Group->LabelWidth;
  792.             }
  793.  
  794.             Group->Width += 2 * (Handle->GlyphWidth + Handle->InterWidth) + 8;
  795.         }
  796.  
  797.         if(Group->Special.Group.IndentX)
  798.         {
  799.             Group->Width                    += 2 * Handle->InterWidth;
  800.             Group->Special.Group.ExtraLeft    += Handle->InterWidth;
  801.         }
  802.  
  803.         if(Group->Special.Group.IndentY)
  804.         {
  805.             Group->Height                    += 2 * Handle->InterHeight;
  806.             Group->Special.Group.ExtraTop    += Handle->InterHeight;
  807.         }
  808.  
  809.         if(ReturnKey)
  810.             Handle->ReturnKey = ReturnKey;
  811.  
  812.         if(EscKey)
  813.             Handle->EscKey = EscKey;
  814.  
  815.         if(CursorKey)
  816.             Handle->CursorKey = CursorKey;
  817.  
  818.         if(TabKey)
  819.             Handle->TabKey = TabKey;
  820.  
  821.         if(ActiveString)
  822.             Handle->ActiveString = ActiveString;
  823.     }
  824. }
  825.